package com.raidan.dclog.core;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.HashSet;
import java.util.ResourceBundle;
import java.util.Set;

public class Utils {

	public final static String getFirstBetweenTags(String string, String tagBody) {
		if (string == null || tagBody == null) {
			return null;
		}
		String tagStart = "<" + tagBody + ">";
		String tagEnd = "</" + tagBody + ">";
		String substring = null;
		int idx = string.indexOf(tagStart);
		if (idx >= 0) {

			int idxEnd = string.indexOf(tagEnd);
			if (idxEnd < idx) {
				return substring;
			}

			substring = string.substring(idx + tagStart.length(), idxEnd).trim();
		}
		return substring;
	}

	/**
	 * Return safe name of file (removing all symbols that can't contain in file
	 * name (in Windows, I mean).
	 * 
	 * @param fileName
	 *            fileName for safe
	 * @return clean name
	 */
	public static String safeFileName(String fileName) {

		if (fileName == null || fileName.length() == 0) {
			return fileName;
		}

		StringBuilder nameB = new StringBuilder(fileName);

		// \ / : * ? " < > |
		replaceAll(nameB, "\\", "_");
		replaceAll(nameB, "/", "_");
		replaceAll(nameB, ":", "_");
		replaceAll(nameB, "*", "_");
		replaceAll(nameB, "?", "_");
		replaceAll(nameB, "\"", "_");
		replaceAll(nameB, "<", "_");
		replaceAll(nameB, ">", "_");
		replaceAll(nameB, "|", "_");

		return nameB.toString();
	}

	private static int MAX_REPLACEABLE_ITERATIONS = 1000000;

	/**
	 * Fast implementation for simple replace data in strings
	 * 
	 * @param buffer
	 * @param replaceWhat
	 * @param replaceTo
	 * @return
	 */
	public final static String replaceAll(String buffer, String replaceWhat, String replaceTo) {
		if (buffer == null || replaceWhat == null) {
			return null;
		}
		return replaceAll(new StringBuilder(buffer), replaceWhat, replaceTo).toString();
	}

	/**
	 * Fast implementation for simple replace data in strings
	 * 
	 * @param buffer
	 * @param replaceWhat
	 * @param replaceTo
	 * @return
	 */
	public final static StringBuilder replaceAll(StringBuilder buffer, String replaceWhat, String replaceTo) {
		if (buffer == null || replaceWhat == null) {
			return null;
		}

		int idx = buffer.indexOf(replaceWhat);
		if (idx >= 0) {
			int cnt = 0;
			int len = replaceWhat.length();
			int len_to = replaceTo.length();
			while (idx >= 0) {
				buffer.replace(idx, idx + len, replaceTo);
				cnt++;
				if (cnt > MAX_REPLACEABLE_ITERATIONS) {
					throw new IllegalStateException("Critical error. Replacing '" + replaceWhat + "' to '" + replaceTo
							+ "' going to infinite loop.");
				}
				idx = buffer.indexOf(replaceWhat, idx + len_to);
			}
		}
		return buffer;
	}

	/**
	 * Parsing text and extracting all macros, that presents. Macros -- words in
	 * % symbols. For example:
	 * 
	 * <pre>
	 * abc - anb % macros % data
	 * </pre>
	 * 
	 * .
	 * 
	 * This method returns <code>new String[]{'macros'}</code>
	 * 
	 * @param text
	 * @return array of macros (without special delimiter symbols)
	 */
	public final static String[] getMacrosList(String text) {
		Set<String> macrosList = new HashSet<String>();

		int idx = -1;
		int idx2 = -1;
		do {
			idx = text.indexOf(Const.MACROS_DEFINITION, idx2 + 1);
			if (idx >= 0) {
				idx2 = text.indexOf(Const.MACROS_DEFINITION, idx + 1);
				if (idx2 > 0) {
					macrosList.add(text.substring(idx + 1, idx2));
				}
			}
		} while (idx >= 0 && idx2 >= 0);

		return macrosList.isEmpty() ? null : macrosList.toArray(new String[0]);

	}

	private static String BUILD_VERSION;

	/**
	 * Return generated string with version info
	 * 
	 * @return string with version info
	 */
	public static synchronized String getVersion() {

		if (BUILD_VERSION == null) {

			String template = ResourceBundle.getBundle("ApplicationResources").getString("version");
			ByteArrayOutputStream byteStream = new ByteArrayOutputStream();

			new PrintStream(byteStream).printf(template, Version.NAME, Version.VERSION, Version.AUTHOR);

			BUILD_VERSION = byteStream.toString();
		}
		return BUILD_VERSION;
	}

	public static synchronized int getBackIndexOf(char text[], char ch, int beforeIndex) {
		for (int i = text.length - 1 - (beforeIndex == 0 ? 0 : text.length - beforeIndex); i >= 0; i--) {
			if (text[i] == ch) {
				return i;
			}
		}
		return -1;
	}
}
